package com.wangsd.web.face.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wangsd.common.basicbean.Result;
import com.wangsd.common.utils.DateUtils;
import com.wangsd.common.utils.HttpClientUtils;
import com.wangsd.web.common.entity.WxMessage;
import com.wangsd.web.face.entity.*;
import com.wangsd.web.face.mapper.AdvertisementMapper;
import com.wangsd.web.face.mapper.AdvertisementStoreRelationMapper;
import com.wangsd.web.face.mapper.StoreMapper;
import com.wangsd.web.face.service.*;
import com.wangsd.web.sys.entity.SysUser;
import com.wangsd.web.sys.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author generator
 * @since 2019-09-10
 */
@Service
@Slf4j
public class StoreServiceImpl extends ServiceImpl<StoreMapper, Store> implements StoreService {
    @Value("${tyt.official.appid}")
    private String appId;

    @Value("${tyt.mini.appid}")
    private String miniAppId;

    @Value("${service.authApiUrl}")
    private String wechatUrl;

    @Resource
    StoreMapper storeMapper;

    @Autowired
    AdvertisementStoreRelationService advertisementStoreRelationService;

    @Autowired
    MerchantService merchantService;

    @Autowired
    AgentService agentService;

    @Autowired
    ServiceBusinessService serviceBusinessService;
    @Autowired
    SysUserService sysUserService;

    @Override
    public IPage<Store> selectList(Integer pageNum, Integer pageSize, Store params, String code) {
        Page<Store> page = new Page<>(pageNum, pageSize);
        IPage<Store> resultIPage = storeMapper.selectListXml(page, params, code);
        return resultIPage;
    }

    @Override
    @Transactional
    public void addOrUpdate(Store params) {
        if (params.getId() != null) {
            storeMapper.updateById(params);
        } else {
            storeMapper.insert(params);

            //保留检索CODE
            Merchant merchant = merchantService.getById(params.getMerchantId());
            params.setCode(merchant.getCode() + "-" + params.getId());
            storeMapper.updateById(params);
        }
    }

   /* @Override
    public Store selectByDeviceId(Long deviceId) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("device_id", deviceId);
        queryWrapper.eq("deleted", "0");
        return storeMapper.selectOne(queryWrapper);
    }*/

    @Override
    public List<Map> selectAllByUserCode(String code) {
        List<Map> resultList = new ArrayList<>();
        QueryWrapper queryWrapper = new QueryWrapper();
        if (StringUtils.isNotBlank(code)) {
            queryWrapper.likeRight("code", code);
        }
        List<Store> list = storeMapper.selectList(queryWrapper);
        for (Store store : list) {
            Map map = new HashMap();
            map.put("code", store.getCode());
            map.put("name", store.getName());
            map.put("id", store.getId());
            resultList.add(map);
        }
        return resultList;
    }

    @Override
    public List<Store> selectAllByCode(String code) {
        QueryWrapper queryWrapper = new QueryWrapper();
        if (StringUtils.isNotBlank(code)) {
            queryWrapper.likeRight("code", code);
        }
        queryWrapper.eq("deleted", "0");
        List<Store> list = storeMapper.selectList(queryWrapper);
        return list;
    }

    @Override
    public List<Store> selectByCode(String code) {
        QueryWrapper queryWrapper = new QueryWrapper();
        if (StringUtils.isNotBlank(code)) {
            queryWrapper.eq("code", code);
        }
        queryWrapper.eq("deleted", "0");
        List<Store> list = storeMapper.selectList(queryWrapper);
        return list;
    }

    @Override
    public JSONArray selectTree(String ctrlType, String displayType, Integer type, String code) {
        List<ServiceBusiness> businessList = null;
        List<Agent> agentList = null;
        List<Merchant> merchantList = null;
        List<Store> storeList = null;
        if (StringUtils.isNotBlank(code)) {
            if (type == 1) {
                /*角色是服务商查询层级*/
                businessList = serviceBusinessService.selectByCode(code);
                agentList = agentService.selectAllByCode(code);
                merchantList = merchantService.selectAllByCode(code);
                storeList = this.selectAllByCode(code);
            } else if (type == 2) {
                /*角色是代理商查询层级*/
                agentList = agentService.selectByCode(code);

                String agentCode = agentList.get(0).getCode();
                String queryBusinessCode = agentCode.substring(0, agentCode.lastIndexOf("-"));
                businessList = serviceBusinessService.selectByCode(queryBusinessCode);

                merchantList = merchantService.selectAllByCode(code);
                storeList = this.selectAllByCode(code);
            } else if (type == 3) {
                /*角色是商户查询层级*/
                merchantList = merchantService.selectByCode(code);

                String merchantCode = merchantList.get(0).getCode();
                String queryAgentCode = merchantCode.substring(0, merchantCode.lastIndexOf("-"));
                agentList = agentService.selectAllByCode(queryAgentCode);

                String agentCode = agentList.get(0).getCode();
                String queryBusinessCode = agentCode.substring(0, agentCode.lastIndexOf("-"));
                businessList = serviceBusinessService.selectByCode(queryBusinessCode);

                storeList = this.selectAllByCode(code);
            } else if (type == 4) {
                /*角色是门店查询层级*/
                storeList = this.selectByCode(code);

                String storeCode = storeList.get(0).getCode();
                String queryStoreCode = storeCode.substring(0, storeCode.lastIndexOf("-"));
                merchantList = merchantService.selectByCode(queryStoreCode);

                String merchantCode = merchantList.get(0).getCode();
                String queryAgentCode = merchantCode.substring(0, merchantCode.lastIndexOf("-"));
                agentList = agentService.selectByCode(queryAgentCode);

                String agentCode = agentList.get(0).getCode();
                String queryBusinessCode = agentCode.substring(0, agentCode.lastIndexOf("-"));
                businessList = serviceBusinessService.selectByCode(queryBusinessCode);
            }
        } else {
            /*超级管理员查询层级*/
            businessList = serviceBusinessService.list();
            agentList = agentService.list();
            merchantList = merchantService.list();
            storeList = storeMapper.selectList(new QueryWrapper<>());
        }
        return packageData(businessList, agentList, merchantList, storeList, ctrlType, displayType);
    }

    @Override
    public Integer selectCountByMerchantId(Long id) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("merchant_id", id);
        queryWrapper.eq("deleted", "0");
        Integer count = storeMapper.selectCount(queryWrapper);
        return count;
    }

    @Override
    public JSONArray selectStoreByArea(String area, String code) {
        QueryWrapper<Store> storeQueryWrapper = new QueryWrapper<>();
        storeQueryWrapper.like("area", area);
        if (StringUtils.isNotBlank(code)) {
            storeQueryWrapper.likeRight("code", code);
        }
        List<Store> stores = storeMapper.selectList(storeQueryWrapper);
        Map<Long, List<Store>> collect = stores.stream().collect(Collectors.groupingBy(Store::getMerchantId));
        List<Merchant> merchantList = merchantService.list();
        JSONArray m_array = new JSONArray();
        for (Long merchantId : collect.keySet()) {
            Optional<Merchant> merchantOptional = merchantList.stream().filter(item -> item.getId().equals(merchantId)).findFirst();
            if (merchantOptional.isPresent()) {
                JSONObject m_object = new JSONObject();
                // 存在,找到对应的商户
                Merchant merchant = merchantOptional.get();
                m_object.put("id", merchant.getId());
                m_object.put("label", merchant.getName());
                JSONArray s_array = new JSONArray();
                List<Store> storeList = collect.get(merchant.getId());
                if (storeList != null) {
                    for (Store store : storeList) {
                        JSONObject s_object = new JSONObject();
                        s_object.put("id", store.getId());
                        s_object.put("label", store.getName());
                        s_array.add(s_object);
                    }
                }
                m_object.put("children", s_array);
                m_array.add(m_object);
            }
        }
        return m_array;
    }

    @Override
    public IPage<Store> selectAdvertisementList(Integer pageNum, Integer pageSize, Store params, String code) {
        Page<Store> page = new Page<>(pageNum, pageSize);
        IPage<Store> resultIPage = storeMapper.selectListXml(page, params, code);
        List<Store> records = resultIPage.getRecords();
        if (records != null) {
            List<Long> storeIds = records.stream().map(Store::getId).collect(Collectors.toList());
            if (storeIds == null || storeIds.size() <= 0) {
                return resultIPage;
            }
            List<Advertisement> advertisements = advertisementStoreRelationService.selectAdvertisementByStoreId(storeIds);
            Map<Long, List<Advertisement>> collect = advertisements.stream().collect(Collectors.groupingBy(Advertisement::getStoreId));
            for (Store store : records) {
                List<Advertisement> list = collect.get(store.getId());
                if (list != null) {
                    store.setUrlList(list.stream().map(Advertisement::getSourceUrl).collect(Collectors.toList()));
                }
            }
        }
        return resultIPage;
    }

    @Override
    public void updateStoreAdvertisement(Store store) {
        advertisementStoreRelationService.remove(new QueryWrapper<AdvertisementStoreRelation>()
                .eq("store_id", store.getId()));
        if (store.getAdvertisementIds() != null) {
            List<AdvertisementStoreRelation> relations = new ArrayList<>();
            for (Long advertisementId : store.getAdvertisementIds()) {
                AdvertisementStoreRelation advertisementStoreRelation = new AdvertisementStoreRelation();
                advertisementStoreRelation.setStoreId(store.getId());
                advertisementStoreRelation.setAdvertisementId(advertisementId);
                relations.add(advertisementStoreRelation);
            }
            advertisementStoreRelationService.saveBatch(relations);
        }
    }


    private JSONArray packageData(List<ServiceBusiness> businessList,
                                  List<Agent> agentList,
                                  List<Merchant> merchantList,
                                  List<Store> storeList, String ctrlType, String displayType) {
        //Map<Long, List<ServiceBusiness>> businessCollect = businessList.stream().collect(Collectors.groupingBy(ServiceBusiness::getId));
        Map<Long, List<Agent>> agentCollect = agentList.stream().collect(Collectors.groupingBy(Agent::getBusinessId));
        Map<Long, List<Merchant>> merchantCollect = merchantList.stream().collect(Collectors.groupingBy(Merchant::getAgentId));
        Map<Long, List<Store>> storeCollect = storeList.stream().collect(Collectors.groupingBy(Store::getMerchantId));
        JSONArray businessArray = new JSONArray();
        if (businessList != null) {
            for (ServiceBusiness serviceBusiness : businessList) {
                JSONObject businessObject = new JSONObject();
                businessObject.put("title", serviceBusiness.getName());
                businessObject.put("key", serviceBusiness.getCode());
                businessObject.put("value", serviceBusiness.getCode());
                if (StringUtils.isNotBlank(ctrlType)) {
                    if (ctrlType.contains("1")) {
                        businessObject.put("disabled", true);
                    }
                }
                if (displayType.contains("2")) {
                    /*拼装代理商*/
                    JSONArray agentArray = new JSONArray();
                    List<Agent> agents = agentCollect.get(serviceBusiness.getId());
                    if (agents != null) {
                        for (Agent agent : agents) {
                            JSONObject agentObject = new JSONObject();
                            agentObject.put("title", agent.getName());
                            agentObject.put("key", agent.getCode());
                            agentObject.put("value", agent.getCode());
                            if (StringUtils.isNotBlank(ctrlType)) {
                                if (ctrlType.contains("2")) {
                                    agentObject.put("disabled", true);
                                }
                            }
                            if (displayType.contains("3")) {
                                JSONArray merchantArray = new JSONArray();
                                List<Merchant> merchants = merchantCollect.get(agent.getId());
                                if (merchants != null) {
                                    for (Merchant merchant : merchants) {
                                        JSONObject merchantObject = new JSONObject();
                                        merchantObject.put("title", merchant.getName());
                                        merchantObject.put("key", merchant.getCode());
                                        merchantObject.put("value", merchant.getCode());
                                        if (StringUtils.isNotBlank(ctrlType)) {
                                            if (ctrlType.contains("3")) {
                                                merchantObject.put("disabled", true);
                                            }
                                        }
                                        if (displayType.contains("4")) {
                                            JSONArray storeArray = new JSONArray();
                                            List<Store> stores = storeCollect.get(merchant.getId());
                                            if (stores != null) {
                                                for (Store store : stores) {
                                                    JSONObject storeObject = new JSONObject();
                                                    storeObject.put("title", store.getName());
                                                    storeObject.put("key", store.getCode());
                                                    storeObject.put("value", store.getCode());
                                                    if (StringUtils.isNotBlank(ctrlType)) {
                                                        if (ctrlType.contains("4")) {
                                                            storeObject.put("disabled", true);
                                                        }
                                                    }
                                                    storeArray.add(storeObject);
                                                }
                                            }
                                            merchantObject.put("children", storeArray);
                                        }
                                        merchantArray.add(merchantObject);
                                    }
                                }
                                agentObject.put("children", merchantArray);
                            }
                            agentArray.add(agentObject);
                        }
                    }
                    businessObject.put("children", agentArray);
                }
                businessArray.add(businessObject);
            }
        }

        return businessArray;
    }


    public void sendWxTempLateReceivables(TOrder order) {
        try {
            SysUser user = sysUserService.getById(order.getStoreUserId());
            if (user == null || user.getType() != 4 || StringUtils.isBlank(user.getOpenId())) {
                return;
            }
            //单人发送模板消息请求地址
            String tempLateUrl = wechatUrl + "/api/wxTemplate/sendTemplate";
            //消息内容
            WxMessage wxMessage = new WxMessage();
            wxMessage.setFirst("您有一笔新的收款");

            Store store = storeMapper.selectById(order.getStoreId());

            wxMessage.setKeyword1(store.getName());
            //支付方式
            String payWay = order.getPayType() == 1 ? "微信" : order.getPayType() == 2 ? "支付宝" : order.getPayType() == 3 ? "会员支付" : order.getPayType() == 4 ? "通用通" : "其他";

            //处理实际支付金额
            Long payTotal = order.getMemberTotalFee();//原价
            BigDecimal bg = new BigDecimal(payTotal * 0.01);
            DecimalFormat df1 = new DecimalFormat("0.00");
            String str = df1.format(bg);
            wxMessage.setKeyword2(payWay + " " + str + " 元");

            wxMessage.setKeyword3(DateUtils.formatDate(order.getCreatedTime(), "yyyy-MM-dd HH:mm"));
            wxMessage.setKeyword4(order.getOutTradeNo());
            wxMessage.setRemark("点击查看更多详情");
            //跳转小程序设置
            wxMessage.setMiniAppid(miniAppId);
            wxMessage.setPagePath("pages/transaction/index");

            //发送设置
            Map params = new HashMap();
            params.put("wxMessage", JSON.toJSONString(wxMessage));//消息内容体String
            params.put("templateId", "OPENTM416664450");//模板消息ID
            params.put("openId", user.getOpenId());
            params.put("appId", appId);
            String result = HttpClientUtils.post(tempLateUrl, params, "UTF-8");
            log.info(result);
        } catch (Exception e) {
            log.error("订单号：" + order.getOutTradeNo() + ",店员ID：" + order.getStoreUserId() + ",发送收款通知模板消息失败");
        }
    }
}
